package com.icinfo.cloud.provider.punish.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.provider.common.enums.CertTypeEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.punish.app.enums.AppCaseConvertTemporaryEnum;
import com.icinfo.cloud.provider.punish.app.model.AppCaseConvertTemporaryRecord;
import com.icinfo.cloud.provider.punish.dto.AppCaseConvertTemporaryRecordDto;
import com.icinfo.cloud.provider.punish.dto.AppCaseGetConvertTemporaryInfoDto;
import com.icinfo.cloud.provider.punish.dto.SimpleCaseSaveDto;
import com.icinfo.cloud.provider.punish.mapper.AppCaseConvertTemporaryRecordMapper;
import com.icinfo.cloud.provider.punish.service.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.PartyTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseMainDetailInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CasePartiesLegalInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CasePartiesPersonInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CasePartiesRecord;
import com.icinfo.cloud.provider.punish.ucase.caseregister.dto.CaseRegisterPartiesLegalInfoDto;
import com.icinfo.cloud.provider.punish.ucase.caseregister.dto.CaseRegisterPartiesPersonInfoDto;
import com.icinfo.cloud.provider.punish.ucase.caseregister.vo.CaseRegisterInfoVo;
import com.icinfo.cloud.provider.punish.ucase.punishinform.dto.AppInformInvestigationEndFormDto;
import com.icinfo.cloud.provider.punish.ucase.punishinform.vo.PunishRuleInfo;
import com.icinfo.cloud.provider.punish.ucase.punishinform.vo.ViolateRuleInfo;
import com.icinfo.cloud.provider.punish.vo.SimpleCaseInfoVo;
import com.icinfo.cloud.xzcf.provider.member.userinfo.dto.UserDTO;
import com.icinfo.framework.core.service.support.MyBatisServiceSupport;
import com.icinfo.framework.tools.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;


/**
 * @author HKxxx
 * description 针对表【app_case_convert_temporary_record(普通案件与简单案件转换临时数据表)】的数据库操作Service实现
 * createDate 2024-03-15 16:09:19
 */
@Slf4j
@Service
public class AppCaseConvertTemporaryRecordServiceImpl extends MyBatisServiceSupport implements IAppCaseConvertTemporaryRecordService {

    @Resource
    private AppCaseConvertTemporaryRecordMapper appCaseConvertTemporaryMapper;

    @Resource
    private ICasePartiesRecordService casePartiesRecordService;

    @Resource
    private ICasePartiesLegalInfoService casePartiesLegalInfoService;

    @Resource
    private ICasePartiesPersonInfoService casePartiesPersonInfoService;

    @Resource
    private ICaseMainDetailInfoService caseMainDetailInfoService;

    @Resource
    private ICaseHandlePersonRecordService caseHandlePersonRecordService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(AppCaseConvertTemporaryRecordDto dto) {
        UserDTO user = getUser();
        // 清理临时数据
        removeCurrentUserConvertTemporaryRecord(dto.getConvertType());
        // 组装数据
        AppCaseConvertTemporaryRecord temporaryRecord = assemblyTemporaryRecord(dto, user);
        // 插入
        appCaseConvertTemporaryMapper.insert(temporaryRecord);
    }

    @Override
    public JSONObject getCurrentUserConvertTemporaryInfo(AppCaseGetConvertTemporaryInfoDto dto) {
        AppCaseConvertTemporaryRecord temporaryRecord = getAppCaseConvertTemporaryRecord(dto);
        if (Objects.isNull(temporaryRecord)) {
            throw new BusinessException("当前账号无案件转换临时数据");
        }
        return JSONObject.parseObject(temporaryRecord.getAfterContent());
    }

    private AppCaseConvertTemporaryRecord getAppCaseConvertTemporaryRecord(AppCaseGetConvertTemporaryInfoDto dto) {
        UserDTO user = getUser();
        AppCaseConvertTemporaryRecord query = new AppCaseConvertTemporaryRecord();
        query.setConvertType(dto.getConvertType().getCode());
        query.setAddUser(String.valueOf(user.getUserId()));
        query.setOrgCode(user.getOrgCode());
        query.setAreaCode(user.getAreaCode());
        return appCaseConvertTemporaryMapper.selectOne(query);
    }

    /**
     * 组装实体模型
     */
    private AppCaseConvertTemporaryRecord assemblyTemporaryRecord(AppCaseConvertTemporaryRecordDto dto, UserDTO user) {
        AppCaseConvertTemporaryRecord temporaryRecord = new AppCaseConvertTemporaryRecord();
        temporaryRecord.setId(StringUtils.uuid());
        temporaryRecord.setConvertType(dto.getConvertType().getCode());
        temporaryRecord.setBeforeContent(JSON.toJSONString(dto));
        temporaryRecord.setAfterContent(convertData(dto));
        temporaryRecord.setCreateTime(new Date());
        temporaryRecord.setAddUser(String.valueOf(user.getUserId()));
        temporaryRecord.setOrgCode(user.getOrgCode());
        temporaryRecord.setAreaCode(user.getAreaCode());
        return temporaryRecord;
    }

    /**
     * 根据转换类型转换内容
     */
    private String convertData(AppCaseConvertTemporaryRecordDto dto) {
        String content = "";
        if (AppCaseConvertTemporaryEnum.NORMAL_CONVERT.equals(dto.getConvertType())) {
            // 简易转普通
            SimpleCaseSaveDto beforeDto = JSONObject.parseObject(dto.getContent(), SimpleCaseSaveDto.class);
            content = JSON.toJSONString(convertToNormalInfo(beforeDto));
        } else {
            // 普通转简易
            AppInformInvestigationEndFormDto beforeDto = JSONObject.parseObject(dto.getContent(), AppInformInvestigationEndFormDto.class);
            content = JSON.toJSONString(convertToSimple(dto, beforeDto));
        }
        return content;
    }

    /**
     * 普通转简易
     */
    private SimpleCaseInfoVo convertToSimple(AppCaseConvertTemporaryRecordDto dto, AppInformInvestigationEndFormDto beforeDto) {
        // 组装当事人信息
        SimpleCaseInfoVo simpleCaseInfoVo = assemblePartiesInfo(beforeDto);
        // 处罚事项
        simpleCaseInfoVo.setCaseReasonCode(beforeDto.getCaseReasonCode());
        simpleCaseInfoVo.setCaseReasonId(beforeDto.getCaseReasonNodeid().split(",")[1]);
        simpleCaseInfoVo.setCaseReasonName(beforeDto.getCaseReason());
        simpleCaseInfoVo.setCatalogId(dto.getCatalogId());
        simpleCaseInfoVo.setClaimId(beforeDto.getClaimId());
        // 罚则
        simpleCaseInfoVo.setPunishDetail(getPunishBasis(beforeDto.getPunishRuleInfos()));
        // 违则
        simpleCaseInfoVo.setIllegalBasis(getIllegalBasis(beforeDto.getViolateRuleInfos()));
        // 违法情形id
        simpleCaseInfoVo.setIllegalSituation(beforeDto.getIllegalSituation());
        // 反应内容-简要情况
        CaseMainDetailInfo caseMainDetailInfo = caseMainDetailInfoService.getCaseMainDetailInfoByCaseId(beforeDto.getCaseId());
        simpleCaseInfoVo.setCaseReactionContent(Objects.isNull(caseMainDetailInfo) ? "" : caseMainDetailInfo.getCaseConciseCondition());
        // 执法信息
        simpleCaseInfoVo.setHandlePersonInfoList(caseHandlePersonRecordService.getCaseHandlePersonRecordByCaseId(beforeDto.getCaseId()));
        return simpleCaseInfoVo;
    }

    /**
     * 组装案件当事人信息
     */
    private SimpleCaseInfoVo assemblePartiesInfo(AppInformInvestigationEndFormDto beforeDto) {
        // 初始化返回对象
        SimpleCaseInfoVo simpleCaseInfoVo = new SimpleCaseInfoVo();
        // 当事人记录
        List<CasePartiesRecord> casePartiesInfoByCaseId = casePartiesRecordService.getCasePartiesInfoByCaseId(beforeDto.getCaseId());
        // 移动端的普通案件只涉及单当事人，只取第一个
        CasePartiesRecord casePartiesRecord = casePartiesInfoByCaseId.stream().findFirst().orElse(null);
        if (Objects.isNull(casePartiesRecord)) {
            return simpleCaseInfoVo;
        }
        // 不同类型的当事人存在不同的表中
        if (PartyTypeEnum.PERSON.getCode().equals(casePartiesRecord.getPartyType())) {
            assemblePersonInfo(simpleCaseInfoVo, casePartiesRecord.getPartyId());
        } else {
            assembleLegalInfo(simpleCaseInfoVo, casePartiesRecord.getPartyId());
        }
        return simpleCaseInfoVo;
    }

    /**
     * 组装案件当事人-法人信息
     */
    private void assembleLegalInfo(SimpleCaseInfoVo simpleCaseInfoVo, String partyId) {
        CasePartiesLegalInfo legalInfo = casePartiesLegalInfoService.getPartiesLegalInfoById(partyId);
        simpleCaseInfoVo.setPartyType(PartyTypeEnum.LEGAL.getCode());
        simpleCaseInfoVo.setEntName(legalInfo.getEntName());
        simpleCaseInfoVo.setUniscid(legalInfo.getUniscid());
        simpleCaseInfoVo.setUnitAddress(legalInfo.getAddress());
        simpleCaseInfoVo.setLegal(legalInfo.getLegalName());
        simpleCaseInfoVo.setLegalCertType(legalInfo.getLegalCertType());
        simpleCaseInfoVo.setLegalCertNo(legalInfo.getLegalCertNo());
        simpleCaseInfoVo.setEntType(legalInfo.getEntType());
        simpleCaseInfoVo.setBusinessAddress(legalInfo.getBusinessAddress());
        simpleCaseInfoVo.setJob(legalInfo.getJob());
        simpleCaseInfoVo.setPhone(legalInfo.getPhone());
    }

    /**
     * 组装案件当事人-个人信息
     */
    private void assemblePersonInfo(SimpleCaseInfoVo simpleCaseInfoVo, String partyId) {
        CasePartiesPersonInfo personInfo = casePartiesPersonInfoService.getCasePartiesPersonInfoById(partyId);
        simpleCaseInfoVo.setPartyType(PartyTypeEnum.PERSON.getCode());
        simpleCaseInfoVo.setCertType(personInfo.getCertType());
        simpleCaseInfoVo.setCertNo(personInfo.getCertNo());
        simpleCaseInfoVo.setName(personInfo.getName());
        simpleCaseInfoVo.setAddress(personInfo.getAddress());
        simpleCaseInfoVo.setMobile(personInfo.getMobile());
        simpleCaseInfoVo.setSex(personInfo.getSex());
        simpleCaseInfoVo.setAge(String.valueOf(calculateAge(personInfo.getBirth())));
        simpleCaseInfoVo.setUnitName(personInfo.getUnitName());
    }


    /**
     * 获取罚则详情
     */
    private static String getIllegalBasis(List<ViolateRuleInfo> violateRuleInfos) {
        if (CollUtil.isEmpty(violateRuleInfos)) {
            return "";
        }
        ViolateRuleInfo violateRuleInfo = violateRuleInfos.stream().findFirst().orElse(null);
        if (Objects.isNull(violateRuleInfo)) {
            return "";
        }
        return violateRuleInfo.getIllegalBasis();
    }

    /**
     * 获取罚则详情
     */
    private static String getPunishBasis(List<PunishRuleInfo> punishRuleInfos) {
        if (CollUtil.isEmpty(punishRuleInfos)) {
            return "";
        }
        PunishRuleInfo punishRuleInfo = punishRuleInfos.stream().findFirst().orElse(null);
        if (Objects.isNull(punishRuleInfo)) {
            return "";
        }
        return punishRuleInfo.getPunishBasis();
    }

    /**
     * 简易转普通程序
     */
    private CaseRegisterInfoVo convertToNormalInfo(SimpleCaseSaveDto beforeDto) {
        // 初始化转换后的vo
        CaseRegisterInfoVo caseRegisterInfoVo = new CaseRegisterInfoVo();
        // 当事人信息
        if (PartyTypeEnum.PERSON.getCode().equals(beforeDto.getPartyType())) {
            // 个人
            caseRegisterInfoVo.setPartiesPersonInfoList(Collections.singletonList(assemblePersonPartiesInfo(beforeDto)));
        } else {
            // 法人
            caseRegisterInfoVo.setPartiesLegalInfoList(Collections.singletonList(assembleLegalPartiesInfo(beforeDto)));
        }
        // 取证信息
        caseRegisterInfoVo.setCaseHappenAddress(beforeDto.getCaseHappenAddressDetail());
        caseRegisterInfoVo.setCaseConciseCondition(beforeDto.getCaseReactionContent());
        caseRegisterInfoVo.setCaseHappenTime(StrUtil.isBlank(beforeDto.getCaseHappenTime()) ? null : beforeDto.getCaseHappenTime().substring(0, 10));
        // 处罚信息
        caseRegisterInfoVo.setCaseName(beforeDto.getCaseName());
        // 办案人员
        caseRegisterInfoVo.setHandlePersonInfoList(beforeDto.getHandlePersonInfoList());
        return caseRegisterInfoVo;
    }


    /**
     * 组装当事人-个人信息
     */
    private static CaseRegisterPartiesLegalInfoDto assembleLegalPartiesInfo(SimpleCaseSaveDto beforeDto) {
        CaseRegisterPartiesLegalInfoDto legalInfo = new CaseRegisterPartiesLegalInfoDto();
        legalInfo.setEntName(beforeDto.getEntName());
        legalInfo.setUniscid(beforeDto.getUniscid());
        legalInfo.setUnitAddress(beforeDto.getAddress());
        legalInfo.setLegal(beforeDto.getLegal());
        legalInfo.setLegalCertType(beforeDto.getLegalCertType());
        legalInfo.setLegalCertNo(beforeDto.getLegalCertNo());
        legalInfo.setEntType(beforeDto.getEntType());
        legalInfo.setBusinessAddress(beforeDto.getBusinessAddress());
        legalInfo.setJob(beforeDto.getJob());
        legalInfo.setPhone(beforeDto.getPhone());
        return legalInfo;
    }

    /**
     * 组装当事人-法人信息
     */
    private static CaseRegisterPartiesPersonInfoDto assemblePersonPartiesInfo(SimpleCaseSaveDto beforeDto) {
        CaseRegisterPartiesPersonInfoDto partiesInfo = new CaseRegisterPartiesPersonInfoDto();
        // 类型为身份证
        if (CertTypeEnum.SFZ.getCode().equals(beforeDto.getCertType())) {
            partiesInfo.setBirth(extractBirthDate(beforeDto.getCertNo()));
        }
        partiesInfo.setCertType(beforeDto.getCertType());
        partiesInfo.setCertNo(beforeDto.getCertNo());
        partiesInfo.setName(beforeDto.getName());
        partiesInfo.setAddress(beforeDto.getAddress());
        partiesInfo.setMobile(beforeDto.getMobile());
        partiesInfo.setSex(beforeDto.getSex());
        partiesInfo.setUnitName(beforeDto.getUnitName());
        return partiesInfo;
    }


    /**
     * 提取身份证的出生日期
     */
    public static String extractBirthDate(String idCardNumber) {
        if (idCardNumber == null || idCardNumber.length() != 18) {
            // 如果身份证号码无效或长度不正确，返回null
            return null;
        }
        // 提取第7到14位的生日
        String birthDateStr = idCardNumber.substring(6, 14);
        // 确保这8位都是数字
        if (!birthDateStr.matches("\\d{8}")) {
            // 如果生日部分不是数字，返回null
            return null;
        }
        String year = birthDateStr.substring(0, 4);
        String month = birthDateStr.substring(4, 6);
        String day = birthDateStr.substring(6, 8);
        // 转换为 "yyyy-MM-dd" 格式
        return year + "-" + month + "-" + day;
    }


    /**
     * 获取出生日期到当前时间的精确年龄
     */
    public static Integer calculateAge(String birthDateString) {
        if (StrUtil.isBlank(birthDateString)) {
            return null;
        }
        LocalDate birthDate = null;
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
            birthDate = LocalDate.parse(birthDateString, formatter);
        } catch (Exception e) {
            throw new BusinessException("时间格式化错误");
        }
        LocalDate currentDate = LocalDate.now();

        long years = ChronoUnit.YEARS.between(birthDate, currentDate);
        if (birthDate.plusYears(years).isAfter(currentDate)) {
            years--;
        }
        return (int) years;
    }

    /**
     * 移除当前用户的临时数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeCurrentUserConvertTemporaryRecord(AppCaseConvertTemporaryEnum convertType) {
        UserDTO user = getUser();
        AppCaseConvertTemporaryRecord convertTemporary = new AppCaseConvertTemporaryRecord();
        convertTemporary.setAddUser(String.valueOf(user.getUserId()));
        convertTemporary.setOrgCode(user.getOrgCode());
        convertTemporary.setAreaCode(user.getAreaCode());
        convertTemporary.setConvertType(convertType.getCode());
        appCaseConvertTemporaryMapper.delete(convertTemporary);
    }


}




